package com.tencent.sr.iris.activity.service.activity.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.tencent.sr.iris.activity.common.enums.ActivityTaskStatusEnum;
import com.tencent.sr.iris.activity.domain.event.dto.ActivityTaskDTO;
import com.tencent.sr.iris.activity.interfaces.dto.AwardInfoDTO;
import com.tencent.sr.iris.activity.repository.entity.TIrisActivityTaskDO;
import com.tencent.sr.iris.activity.repository.singlemapper.TIrisActivityTaskMapper;
import com.tencent.sr.iris.activity.repository.singlemapper.example.TIrisActivityTaskExample;
import com.tencent.sr.iris.activity.service.activity.IrisActivityTaskService;
import com.tencent.sr.iris.activity.service.constant.ActivityRedisKey;
import com.tencent.sr.iris.activity.service.localcache.LocalCacheManager;
import com.tencent.sr.iris.activity.service.util.BeanConvertUtil;
import com.tencent.sr.rmall.springbootstarter.redis.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

@Slf4j
@Service
public class IrisActivityTaskServiceImpl implements IrisActivityTaskService {

    @Resource
    private TIrisActivityTaskMapper activityTaskMapper;

    @Resource
    private RedisClient redisClient;

    @Override
    public List<TIrisActivityTaskDO> getTasksByIds(List<String> bizIdList) {

        List<String> keys = bizIdList.stream()
                .map(i -> String.format(ActivityRedisKey.ACTIVITY_TASK_CACHE_KEY, i))
                .collect(Collectors.toList());

        List<String> caches = redisClient.mget(keys.toArray(new String[keys.size()]));

        List<String> retryKeys = Lists.newArrayList();
        for (int i = 0; i < caches.size(); i++) {
            String cache = caches.get(i);
            if (StrUtil.isBlank(cache)) {
                retryKeys.add(keys.get(i));
            }
        }

        if (CollectionUtil.isEmpty(retryKeys)) {
            return caches.stream()
                    .map(i -> JSON.parseObject(i, TIrisActivityTaskDO.class))
                    .collect(Collectors.toList());
        }

        //查数据库
        TIrisActivityTaskExample example = new TIrisActivityTaskExample();
        example.createCriteria()
                .andPropertyIn(TIrisActivityTaskExample.BIZ_ID, bizIdList);
        List<TIrisActivityTaskDO> list = activityTaskMapper.selectByExample(example);
        if (CollectionUtil.isNotEmpty(list)) {
            //todo 设置缓存 删除缓存
            list.forEach(i -> redisClient.setex(String.format(ActivityRedisKey.ACTIVITY_TASK_CACHE_KEY,
                    i.getBizId()), JSON.toJSONString(i), 60));
        }

        //重新查询
        caches = redisClient.mget(keys.toArray(new String[keys.size()]));
        return caches.stream().filter(i -> StrUtil.isNotBlank(i))
                .map(i -> JSON.parseObject(i, TIrisActivityTaskDO.class))
                .collect(Collectors.toList());
    }

    @Override
    public List<ActivityTaskDTO> getTasksByActBizId(String actBizId) {
        TIrisActivityTaskExample example = new TIrisActivityTaskExample();
        example.createCriteria().andPropertyEqualTo(TIrisActivityTaskExample.ACTIVITY_ID, actBizId);
        List<TIrisActivityTaskDO> doList = activityTaskMapper.selectByExample(example);
        if (CollectionUtil.isEmpty(doList)) {
            return null;
        }
        List<ActivityTaskDTO> dtoList = BeanConvertUtil.INSTANCE.convertActivityTaskDO2DTOList(doList);
        return dtoList;
    }

    @Override
    public ActivityTaskDTO getTaskByTaskBizId(String actBizId) {
        String taskCacheKey = String.format("task:cache:%s", actBizId);
        String taskStr = redisClient.get(taskCacheKey);
        ActivityTaskDTO activityTaskDTO = null;
        if (Strings.isNullOrEmpty(taskStr)) {
            activityTaskDTO = getActivityTaskDTONoCache(actBizId);
            if (activityTaskDTO == null) {
                return null;
            }
            redisClient.set(taskCacheKey, JSON.toJSONString(activityTaskDTO), "NX", "EX", 60L);
        } else {
            activityTaskDTO = JSON.parseObject(taskStr, ActivityTaskDTO.class);
        }
        return activityTaskDTO;
    }

    @Override
    public AwardInfoDTO getAwardInfoByTaskBizId(String actBizId) {
        ActivityTaskDTO taskDTO = getActivityTaskDTONoCache(actBizId);
        if (taskDTO == null) {
            return null;
        }
        String awardInfo = taskDTO.getAwardInfo();
        if (Strings.isNullOrEmpty(awardInfo)) {
            return null;
        }
        AwardInfoDTO awardInfoDTO = JSON.parseObject(awardInfo, AwardInfoDTO.class);
        return awardInfoDTO;
    }

    private ActivityTaskDTO getActivityTaskDTONoCache(String actBizId) {
        TIrisActivityTaskExample example = new TIrisActivityTaskExample();
        example.createCriteria().andPropertyEqualTo(TIrisActivityTaskExample.BIZ_ID, actBizId);
        List<TIrisActivityTaskDO> doList = activityTaskMapper.selectByExample(example);
        if (CollectionUtil.isEmpty(doList)) {
            return null;
        }
        ActivityTaskDTO dto = BeanConvertUtil.INSTANCE.convertActivityTaskDO2DTO(doList.get(0));
        return dto;
    }

    @Override
    public List<TIrisActivityTaskDO> getAll() {
        return activityTaskMapper.selectByExample(null);
    }

    @Override
    public Map<String, TIrisActivityTaskDO> getAllFromLocalCache() {
        String taskInfoKey = "iris:activity:task:info";
        try {
            return LocalCacheManager.ALL_ACTIVITY_TASK_INFO.get(taskInfoKey, () -> {
                List<TIrisActivityTaskDO> all = getAll();
                return all.stream().collect(Collectors.toMap(
                        TIrisActivityTaskDO::getBizId, i -> i, (i1, i2) -> i1));
            });
        } catch (ExecutionException e) {
            log.error("获取任务信息错误", e);
        }
        return Collections.EMPTY_MAP;
    }

    @Override
    public TIrisActivityTaskDO selectByPrimaryKey(Long id) {
        return activityTaskMapper.selectByPrimaryKey(id);
    }

    /**
     * 获取最新的一条有效配置
     *
     * @param bizId
     * @return
     */
    @Override
    public AwardInfoDTO getValidAwardInfoLastOne(String bizId) {
        TIrisActivityTaskExample example = new TIrisActivityTaskExample();
        example.createCriteria()
                .andPropertyEqualTo(TIrisActivityTaskExample.BIZ_ID, bizId)
                .andPropertyEqualTo(TIrisActivityTaskExample.STATUS, ActivityTaskStatusEnum.NORMAL.getCode());
        example.setOrderByClause(TIrisActivityTaskExample.END_TIME + " desc");
        List<TIrisActivityTaskDO> doList = activityTaskMapper.selectByExample(example);
        if (CollectionUtil.isEmpty(doList)) {
            return null;
        }
        String awardInfo = doList.get(0).getAwardInfo();
        AwardInfoDTO awardInfoDTO = JSON.parseObject(awardInfo, AwardInfoDTO.class);
        return awardInfoDTO;
    }

}
